package com.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dao.dao.IAddressDao;
import com.dao.dao.IGoodsDao;
import com.dao.dao.IOrderDao;
import com.dao.dao.IOrderGoodsDao;
import com.dao.entity.Address;
import com.dao.entity.Goods;
import com.dao.entity.Order;
import com.dao.entity.OrderGoods;
import com.dao.redis.IRedislLoginVerifyDao;
import com.net.base.BaseRequest;
import com.net.base.BaseResponse;
import com.net.bean.GoodsRequestBean;
import com.net.bean.OrderRequestBean;
import com.net.filter.LoginFilter;
import com.util.NetUtil;
import com.util.Utils;

/**
 * 买家业务处理控制器
 * 
 * @author 尚业
 *
 */
@Controller
@RequestMapping(value = "/buyer")
public class BuyerController {
	private static Logger logger = Logger.getLogger(LoginFilter.class);

	@Autowired
	IGoodsDao goodsDao;
	@Autowired
	IOrderDao orderDao;
	@Autowired
	IOrderGoodsDao orderGoodsDao;
	@Autowired
	IAddressDao addressDao;

	@Autowired
	IRedislLoginVerifyDao redislLoginVerifyDao;

	/**
	 * 1.获取事物控制器
	 */
	@Autowired
	DataSourceTransactionManager transactionManager;

	/**
	 * 模糊查询
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/queryGoods")
	@ResponseBody
	public BaseResponse<List<Goods>> queryGoods(HttpServletRequest request,
			@RequestBody BaseRequest<GoodsRequestBean> requestBody) {
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		GoodsRequestBean goodsRequestBean = requestBody.getBody();
		if (goodsRequestBean == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}

		List<Goods> listResult = goodsDao.selective(goodsRequestBean);
		return NetUtil.getDataResponse(listResult, "数据请求成功");
	}
	/**
	 * 分类查询商品，传入offset和limit
	 */
	@RequestMapping(value = "/queryGoodsBySort")
	@ResponseBody
	public BaseResponse<List<Goods>> queryGoodsBySort(HttpServletRequest request,@RequestBody BaseRequest<Map<String, Integer>> requestBody) {
		logger.warn("分类查询商品");
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		Map<String, Integer> mapRequest = requestBody.getBody();
		if (mapRequest == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		String userName = Utils.getUserNameBytaken(redislLoginVerifyDao,
				request.getHeader("JSESSIONID"));
		if (userName == null) {
			return NetUtil.getCommonFailuerResponse("会话过期");
		}
		List<Goods> listResult = goodsDao.selectHotGoods(mapRequest.get("offset"), mapRequest.get("limit"));
		return NetUtil.getDataResponse(listResult, "数据请求成功");
	}
	/**
	 * 主页推荐商品，传入offset和limit
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/showHotGoods")
	@ResponseBody
	public BaseResponse<List<Goods>> showGoods(HttpServletRequest request,@RequestBody BaseRequest<Map<String, Integer>> requestBody) {
		logger.warn("显示货物");
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		Map<String, Integer> mapRequest = requestBody.getBody();
		if (mapRequest == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		String userName = Utils.getUserNameBytaken(redislLoginVerifyDao,
				request.getHeader("JSESSIONID"));
		if (userName == null) {
			return NetUtil.getCommonFailuerResponse("会话过期");
		}
		List<Goods> listResult = goodsDao.selectHotGoods(mapRequest.get("offset"), mapRequest.get("limit"));
		return NetUtil.getDataResponse(listResult, "数据请求成功");
	}

	/**
	 * 买家添加订单
	 * 
	 * @param request
	 * @param requestBody
	 * @return
	 */
	@RequestMapping(value = "/addOrder")
	@ResponseBody
	public BaseResponse<OrderRequestBean> addOrder(HttpServletRequest request,
			@RequestBody BaseRequest<OrderRequestBean> requestBody) {
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		OrderRequestBean orderRequestBean = requestBody.getBody();

		if (orderRequestBean == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		String address = orderRequestBean.getAddress();
		List<OrderGoods> goodsList = orderRequestBean.getGoodsList();
		if (address == null || goodsList == null || goodsList.size() == 0) {
			return NetUtil.getCommonFailuerResponse("请求数据不完整");
		}
		String userName = Utils.getName1Bytaken(redislLoginVerifyDao,
				request.getHeader("JSESSIONID"));
		if (userName == null) {
			return NetUtil.getCommonFailuerResponse("会话过期");
		}

		if (sortAndAddOrder(address, userName, goodsList))
			return NetUtil.getCommonSuccessResponse("下单成功");
		else {
			return NetUtil.getCommonFailuerResponse("下单失败");
		}
	}

	/**
	 * 批量订单生成事务
	 * 
	 * @param userName
	 * @param goodsList
	 * @return
	 */
	private boolean sortAndAddOrder(String address, String userName,
			List<OrderGoods> goodsList) {
		boolean flg = false;
		// 2.获取事物定义
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		// 3.设置事务隔离级别，开启新事务
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
		// 4.获得事务状态
		TransactionStatus status = transactionManager.getTransaction(def);
		try {
			// 根据物品id找出商家sellerName并分类;
			Map<String, List<OrderGoods>> sortOrder = new HashMap<String, List<OrderGoods>>();
			Map<String, Double> prices = new HashMap<String, Double>();
			for (int i = 0; i < goodsList.size(); i++) {
				String sellerName = goodsList.get(i).getUsername();
				if (sortOrder.containsKey(sellerName)) {
					List<OrderGoods> listGoods = sortOrder.get(sellerName);
					Double price = prices.get(sellerName);
					listGoods.add(goodsList.get(i));
					price += goodsList.get(i).getPrice()*goodsList.get(i).getNum();
					sortOrder.replace(sellerName, listGoods);
					prices.replace(sellerName, price);
				} else {
					List<OrderGoods> listGoods = new ArrayList<OrderGoods>();
					listGoods.add(goodsList.get(i));
					sortOrder.put(sellerName, listGoods);
					prices.put(sellerName, goodsList.get(i).getPrice()*goodsList.get(i).getNum());
				}
			}
			// 分类后的物品，生成批量订单
			Iterator<Entry<String, List<OrderGoods>>> iter = sortOrder
					.entrySet().iterator();
			Iterator<Entry<String, Double>> iterator = prices.entrySet().iterator();
			while (iter.hasNext()) {
				Entry<String, List<OrderGoods>> entry = iter.next();
				Entry<String, Double> entry2 = iterator.next();
				String sellerName = entry.getKey();
				List<OrderGoods> listGoods = entry.getValue();
				Order order = new Order();
				order.setPrice(entry2.getValue());
				order.setCommentstatus(false);
				order.setAddr(address);
				order.setSellername(sellerName);
				order.setCreatetime(new Date());
				order.setState(0);
				order.setUsername(userName);
				addOrder(order, listGoods);
			}
			transactionManager.commit(status);
			flg = true;
		} catch (Exception e) {
			transactionManager.rollback(status);
			logger.error("订单生成错误", e);
		}
		return flg;
	}

	/**
	 * 添加单个订单
	 * 
	 * @param order
	 * @param goodsList
	 * @return
	 */
	private void addOrder(Order order, List<OrderGoods> goodsList) {
		orderDao.insert(order);
		int newOrderID = orderDao.selectMaxOrderId();
		for (int i = 0; i < goodsList.size(); i++) {
			goodsList.get(i).setOrderid(newOrderID);
			goodsList.get(i).setCommentstatus(false);
			orderGoodsDao.insert(goodsList.get(i));
		}
	}

	/**
	 * 添加收获地址
	 * 
	 * @param request
	 * @param requestBody
	 * @return
	 */
	@RequestMapping(value = "/addAddress")
	@ResponseBody
	public BaseResponse<Object> addAddress(HttpServletRequest request,
			@RequestBody BaseRequest<Address> requestBody) {
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		Address address = NetUtil.getBodyFromBaseRequest(requestBody,
				Address.class);
		if (address == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		String userName = Utils.getUserNameBytaken(redislLoginVerifyDao,
				request.getHeader("JSESSIONID"));
		if (userName == null) {
			return NetUtil.getCommonFailuerResponse("会话过期");
		}
		address.setUsername(userName);
		address.setIsDefault(false);
		return NetUtil.returnResponseByDbCode(addressDao.insert(address));
	}

	/**
	 * 删除收获地址
	 * 
	 * @param request
	 * @param requestBody
	 * @return
	 */
	@RequestMapping(value = "/deleteAddress")
	@ResponseBody
	public BaseResponse<Object> deleteAddress(HttpServletRequest request,
			@RequestBody BaseRequest<Map<String, Integer>> requestBody) {
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		Map<String, Integer> addressID = requestBody.getBody();
		if (addressID == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}

		return NetUtil.returnResponseByDbCode(addressDao
				.deleteByPrimaryKey(addressID.get("id")));
	}

	/**
	 * 更新收获地址
	 * 
	 * @param request
	 * @param requestBody
	 * @return
	 */
	@RequestMapping(value = "/updateAddress")
	@ResponseBody
	public BaseResponse<Object> updateAddress(HttpServletRequest request,
			@RequestBody BaseRequest<Address> requestBody) {
		if (requestBody == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		Address address = NetUtil.getBodyFromBaseRequest(requestBody,
				Address.class);
		if (address == null) {
			return NetUtil.getCommonFailuerResponse("请求数据为空");
		}
		String userName = Utils.getUserNameBytaken(redislLoginVerifyDao,
				request.getHeader("JSESSIONID"));
		if (userName == null) {
			return NetUtil.getCommonFailuerResponse("会话过期");
		}
		if (address.getIsDefault() != null) {
			List<Address> listAddresses = addressDao.selectByUserName(userName);
			Address oldDefaultAddress = null;
			for (int i = 0; i < listAddresses.size(); i++) {
				Boolean isDefault = listAddresses.get(i).getIsDefault();
				if (isDefault != null && isDefault) {
					oldDefaultAddress = listAddresses.get(i);
					break;
				}
			}
			if (oldDefaultAddress == null) {
				return NetUtil.returnResponseByDbCode(addressDao
						.updateByPrimaryKeySelective(address));
			}else{
				oldDefaultAddress.setIsDefault(false);
				return updateDefaultAddress(oldDefaultAddress,address);
			}
		} else {
			address.setUsername(userName);
			Address newAddress = addressDao.selectByPrimaryKey(address.getId());
			newAddress.setAddr(address.getAddr());
			newAddress.setRecname(address.getRecname());
			newAddress.setPhone(address.getPhone());
			return NetUtil.returnResponseByDbCode(addressDao
					.updateByPrimaryKeySelective(newAddress));
		}
	}

	private BaseResponse<Object> updateDefaultAddress(Address oldDefaultAddress,Address address ) {
		boolean flg = false;
		// 2.获取事物定义
		DefaultTransactionDefinition def = new DefaultTransactionDefinition();
		// 3.设置事务隔离级别，开启新事务
		def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
		// 4.获得事务状态
		TransactionStatus status = transactionManager.getTransaction(def);
		try {
			addressDao.updateByPrimaryKeySelective(oldDefaultAddress);
			addressDao.updateByPrimaryKeySelective(address);
			transactionManager.commit(status);
			flg = true;
		} catch (Exception e) {
			transactionManager.rollback(status);
			logger.error("修改地址错误", e);
		}
		if(flg){
			return NetUtil.getCommonSuccessResponse("修改成功");
		}else{
			return NetUtil.getCommonFailuerResponse("修改失败");
		}
	}

	/**
	 * 查找所有收货地址
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/queryAddress")
	@ResponseBody
	public BaseResponse<List<Address>> queryAddress(HttpServletRequest request) {
		String userName = Utils.getUserNameBytaken(redislLoginVerifyDao,
				request.getHeader("JSESSIONID"));
		if (userName == null) {
			return NetUtil.getCommonFailuerResponse("会话过期");
		}
		List<Address> addressList = addressDao.selectByUserName(userName);
		if (addressList.isEmpty()) {
			return NetUtil.getCommonFailuerResponse("没有查找到地址信息");
		}
		
		return NetUtil.getDataResponse(addressList, "查询成功");
	}
}
